package com.zzyl.oss;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.model.*;
import com.aliyuncs.exceptions.ClientException;
import org.springframework.stereotype.Component;


import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Component
public class AliyunOSSUtil {
//    @Value("${aliyun.oss.endpoint}")
//    private String endpoint;
//    @Value("${aliyun.oss.bucketName}")
//    private String bucketName;

//    @Autowired
    private AliyunOSSProperties aliyunOSSProperties;
//    @Autowired
//    private EmpMapper empMapper;

    public AliyunOSSUtil(AliyunOSSProperties aliyunOSSProperties) {//模拟第三方bean
        this.aliyunOSSProperties = aliyunOSSProperties;
    }

    //上传文件到阿里云OSS
    public String upload(InputStream is, String originalName) throws ClientException {
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
//        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
//        String endpoint = "https://oss-cn-beijing.aliyuncs.com";//北京节点
//        // 填写Bucket名称，例如examplebucket。
//        String bucketName = "web-ai-cs90";
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket里面Object（文件）完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
        String fileName = UUID.randomUUID().toString().replaceAll("-", "");
        String ffix = originalName.substring(originalName.lastIndexOf("."));
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yy/MM/dd/"));
        String objectName = datePath + fileName + ffix;

        // 创建OSSClient实例。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .build();

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, is);
            // 如果需要上传时设置存储类型和访问权限，请参考以下示例代码。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上传文件。
            ossClient.putObject(putObjectRequest);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return "https://" + bucketName + "." + endpoint.split("://")[1] + "/" + objectName;
    }

//    //0.清理垃圾阿里云OSS图片
//    public void cleanup() throws ClientException {
//        List<String> imgList = new ArrayList<>();
//        String endpoint = aliyunOSSProperties.getEndpoint();
//        String bucketName = aliyunOSSProperties.getBucketName();
//        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
//        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
//        // 创建OSSClient实例。
//        OSS ossClient = OSSClientBuilder.create()
//                .endpoint(endpoint)
//                .credentialsProvider(credentialsProvider)
//                .build();
//        ObjectListing objectListing = ossClient.listObjects(bucketName);
//        try {
//            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
//                String imgUrl = "https://" + bucketName + "." + endpoint.split("//")[1] + "/" + objectSummary.getKey();
//                if (!findInDatabase(imgUrl)) {
//                    // 删除文件或目录。如果要删除目录，目录必须为空。
//                    ossClient.deleteObject(bucketName, objectSummary.getKey());
//                }
//            }
//        } finally {
//            if (ossClient != null) {
//                ossClient.shutdown();
//            }
//        }
//
//    }
//
//    //清理数据库中没有但阿里云OSS有的图片
//    private boolean findInDatabase(String imgUrl) {
//        List<String> list = empMapper.queryAllImg();
//        for (String s : list) {
//            if (imgUrl.equals(s)) {
//                return true;
//            }
//        }
//        return false;
//    }

    //1.列举指定数量的阿里云OSS文件
    public List<String> listFile(String keyPrefix) throws ClientException {
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 创建OSSClient实例。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .build();

        try {
            // 列举包含指定前缀的文件。默认列举100个文件。
            ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix(keyPrefix));
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            //将所有的文件路径收集到集合中
            if (!sums.isEmpty()) {
                List<String> fileList = sums.stream().map(OSSObjectSummary::getKey).collect(Collectors.toList());
//                fileList.forEach(System.out::println);
                return fileList;
            }
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }


    //2.分页列举指定数量的阿里云OSS文件
    public List<String> pageListFile(int maxKeys, String keyPrefix) throws ClientException {//参数为每页展示的文件数和文件前缀
        List<String> fileList = new ArrayList<>();
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();

        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 创建OSSClient实例。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .build();

        try {
            String nextMarker = null;
            ObjectListing objectListing;

            do {
                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix(keyPrefix).withMarker(nextMarker).withMaxKeys(maxKeys));

                List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
                //将所有的文件路径收集到集合中
                if (!sums.isEmpty()) {
                    fileList = sums.stream().map(OSSObjectSummary::getKey).collect(Collectors.toList());
//                    fileList.forEach(System.out::println);
                    return fileList;
                }

                nextMarker = objectListing.getNextMarker();

            } while (objectListing.isTruncated());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return fileList;
    }


    //3.删除单个阿里云OSS文件
    public void deleteSingleFile(String objectName) throws ClientException {//参数为要删除的文件名
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写文件完整路径。文件完整路径中不能包含Bucket名称。
        // 创建OSSClient实例。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .build();

        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(bucketName, objectName);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


    //4.批量删除多个阿里云OSS文件
    public void deleteBatchFile(List<String> keys) throws ClientException {//列表查询出的文件作为入参代表要删除的文件
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 创建OSSClient实例。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .build();

        try {
            if (!keys.isEmpty()) {
                DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(keys).withEncodingType("url");
                ossClient.deleteObjects(deleteObjectsRequest);
            }
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
